package com.lagou.utils;

import com.lagou.pojo.Configuration;
import com.lagou.pojo.MappedStatement;
import com.lagou.pojo.ResultMap;

import java.sql.ResultSet;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;

/**
 * @Authther: mrwu
 * @date:2021/3/8-03
 * @Description:com.lagou.utils
 */
public class DefaultResultHander implements ResultSetHandler{
    //用来对比最外层是否为同一对象 对应为sql查询出来的每一行（这种方法sql必须必须按照主键排序）
    private String lastKey ="";
    //将最外层的数据按照最外层查询出的值的字符串组合当作key value 为返回的objec
    //在遍历没一行sql 时 从字典中拿出对象 进行赋值
    private HashMap<String,Object> preResultsMap = new HashMap<String, Object>();

    private String currentofkey ="";
    //用来存放需要封装数组对象时的对象值
    private List<Object> ofresult=new ArrayList<>();
    @Override
    public <E> List<E> handerResultSet(ResultSet resultSet, MappedStatement stmt,Configuration config) throws Exception {
        //获取要返回对象的class 全限定名称
        String resultType = stmt.getResultType();
        //怎么获取namesapce 在mapstament 中增加namespace属性
        String resultMapKey = stmt.getNamespace()+resultType;
        ResultMap  resultMap= config.getMappedResultMap().get(resultMapKey);
        if (resultMap!=null){
                /*
                //复杂映射关系
                //获取返回的类对象的真正名称
                resultType =resultMap.getType();
                Object o = Class.forName(resultType).newInstance();
                String javaType = resultMap.getJavaType() !=null ? resultMap.getJavaType():"" ;
                String ofType = resultMap.getOfType() !=null ? resultMap.getOfType():"";
                Object ofobj =ofType=="" ?null:Class.forName(ofType).newInstance();

                Object jobj = javaType=="" ? null :Class.forName(javaType).newInstance();
                String tempKey ="";
                for (int i = 0; i < metaData.getColumnCount(); i++) {
                    // 字段名 优先使用别名
                    String columnName = metaData.getColumnLabel(i+1);
                    // 字段的值
                    Object value = resultSet.getObject(columnName);
                    //根据columnname 获取property （属性名称）
//                    System.out.println("当前解析到的列是"+columnName);
                    ResultMapping resultMapping = resultMap.getResultMappingMap().get(columnName);
                    //获取外层属性
                    String property = resultMapping.getProperty();
                    //获取内层节点的外层封装属性值
                    String parentProperty = resultMapping.getParentProperty();
                    //如果oftype和Javatype 都为null 则说明是最外层值
                   if (resultMapping.getOfType()==null&resultMapping.getJavaType()==null){
                       tempKey += value;
                       //利用反射进行赋值
                       Field field = o.getClass().getDeclaredField(property);
                       field.setAccessible(true);
                       field.set(o,value);
                   }else if (javaType.equals(resultMapping.getJavaType())){

                       //说明当前对象包含另外一个对象
                       Field field1 = o.getClass().getDeclaredField(parentProperty);
                       field1.setAccessible(true);
                       //获取对象包含的对象 并为对应的属性赋值
                       Object o1 = field1.get(o);
                       Field field = o1.getClass().getDeclaredField(property);
                       field.setAccessible(true);
                       field.set(jobj, value);

                   }if (ofType.equals(resultMapping.getOfType())){
                       //说明当前对象包含另外一个对象的集合
                        Field field = ofobj.getClass().getDeclaredField(property);
                        field.setAccessible(true);
                        field.set(ofobj, value);
                        currentofkey = parentProperty;
                    }
                }

                System.out.println(tempKey+"=====tempkey");
                //组装外层obj
                Field field = o.getClass().getDeclaredField(currentofkey);
                field.setAccessible(true);
                //从预存结果字典中查询 如果值不为空则取出
                Object hasobj = preResultsMap.get(tempKey);
                if (hasobj!=null){
                    Field hasobjOfField = hasobj.getClass().getDeclaredField(currentofkey);
                    hasobjOfField.setAccessible(true);
                    //说明是同一个外层对象 将ofobj对象加入到o的ofobj数组中
                    List hasobjoflist =(List)hasobjOfField.get(hasobj);
                    hasobjoflist.add(ofobj);

                    field.set(o, hasobjoflist);
                    preResultsMap.put(tempKey, o);
                } else {
                    //向最后结果中添加对象
                    ofresult = new ArrayList<>();
                    ofresult.add(ofobj);
                    field.set(o,ofresult);
                    preResultsMap.put(tempKey, o);
                    results.add(o);

                }

                 */
            List<Object> objects =new MapResultSetHandler().handerResultSet(resultSet, stmt, config);
            return (List<E>)objects ;
        }else {
            List<Object> objects = new SimpleReslutSetHander().handerResultSet(resultSet, stmt, config);

            return (List<E>) objects;
        }

    }




}
